#ifndef MSGMANAGER_H
#define MSGMANAGER_H

#include <map>
#include <list>
#include <windows.h>
#include "DataFlow.h"

using std::map;
using std::list;

typedef int T_ModuleDescriptor;
typedef int T_LParameter;

class CMsgMod
{
public:
	virtual void MPostMsg(unsigned int type, T_LParameter lp, const DataFlow &data)
	{}
};

class CMsgManager
{
public:	
#define StartMD 10
#define FinishMD 99
	T_ModuleDescriptor RegisterModule(CMsgMod &mod)
	{
		T_ModuleDescriptor fd;

		EnterCriticalSection (&ListLock);
		fd = GetFreeMD();
		if (fd == -1) return -1;
		ModuleMap[fd] = &mod;
		LeaveCriticalSection (&ListLock);

		return fd;
	}

	void UnRegisterModule(T_ModuleDescriptor md)
	{
		EnterCriticalSection (&ListLock);
		if ( ModuleMap.find(md) != ModuleMap.end() )
		{
			ModuleMap.erase(md);
			FreeMD.push_back(md);
		}
		LeaveCriticalSection (&ListLock);
	}

	int MPostMsgTo(T_ModuleDescriptor md, unsigned int msg, T_LParameter lp, const DataFlow &data)
	{
		EnterCriticalSection (&ListLock);
		CMsgMod * mm = GetModule(md);
		if (!mm) return -1;
		mm->MPostMsg(msg, lp, data);
		LeaveCriticalSection (&ListLock);

		return 1;
	}

public:
	CMsgManager()
	{
		for (T_ModuleDescriptor md = StartMD; md < FinishMD; md++)
		{
			FreeMD.push_back(md);
		}

		InitializeCriticalSection (&ListLock);
	}

	CMsgMod * GetModule( T_ModuleDescriptor md )
	{
		map<T_ModuleDescriptor, CMsgMod *>::iterator it;
		it = ModuleMap.find(md);
		if ( it == ModuleMap.end() )
			return NULL;
		return it->second;
	}

	T_ModuleDescriptor GetFreeMD()
	{
		T_ModuleDescriptor md;
		if ( FreeMD.empty() )
		{ return -1; }
		list <T_ModuleDescriptor>::iterator it = FreeMD.begin();
		//UsedMD.push_back(*it);
		md = *it;
		FreeMD.erase(it);
		return md;
	}
private:
	CRITICAL_SECTION   ListLock;

	map<T_ModuleDescriptor, CMsgMod *>	ModuleMap;
	list <T_ModuleDescriptor> FreeMD;
	//list <T_ModuleDescriptor> UsedMD;
};

CMsgManager *GetMsgManager();











#endif